// const path = 
// CleanWebpackPlugin帮助你在打包时自动清除dist文件，学习时使用比较方便
// const { CleanWebpackPlugin } = require("clean-webpack-plugin"); //从webpack5开始，webpack内置了该功能，只要在ouput中配置clear为true即可

// HtmlWebpackPlugin帮助你创建html文件，并自动引入打包输出的bundles文件。支持html压缩。
const HtmlWebpackPlugin = require("html-webpack-plugin");

// 该插件将CSS提取到单独的文件中。它会为每个chunk创造一个css文件。需配合loader一起使用
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

// 该插件将在Webpack构建过程中搜索CSS资源，并优化\最小化CSS
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");

// vue-loader V15版本以上，需要引入VueLoaderPlugin插件，它的作用是将你定义过的js、css等规则应用到vue文件中去。
const { VueLoaderPlugin } = require('vue-loader')

const config = {
	entry: {
		app: './src/app.js',
		vendors: './src/vendors.js'
	},
	output: {
		// 输出文件目录（将来所有资源输出的公共目录，包括css和静态文件等等）
		path: path.resolve(__dirname, "dist"), //默认
		// 入口文件名称（指定名称+目录）
		filename: "[name].js", // 默认
		// 所有资源引入公共路径前缀，一般用于生产环境，小心使用
		publicPath: "",
		/* 
		非入口文件chunk的名称。所谓非入口即import动态导入形成的chunk或者optimization中的splitChunks提取的公共chunk
		它支持和 filename 一致的内置变量
		*/
		chunkFilename: "[contenthash:10].chunk.js",
		clean: true, // 打包前清空输出目录，相当于clean-webpack-plugin插件的作用,webpack5新增。
		/* 当用 Webpack 去构建一个可以被其他模块导入使用的库时需要用到library */
		library: {
			name: "[name]",//整个库向外暴露的变量名
			type: "window"//库暴露的方式
		}
	},
	loader: {
		rules: [
			{
				// 匹配哪些文件
				test: /\.css$/,
				// 使用哪些loader进行处理。执行顺序，从右至左，从下至上
				use: [
					// 创建style标签，将js中的样式资源（就是css-loader转化成的字符串）拿过来，添加到页面head标签生效
					"style-loader",
					// 将css文件变成commonjs一个模块加载到js中，里面的内容是样式字符串
					"css-loader",
					{
						// css 兼容处理 postcss，注意需要在package.json配置browserslist
						loader: "postcss-loader",
						options: {
							postcssOptions: {
								ident: "postcss",
								// postcss-preset-env插件：帮postcss找到package.json中的browserslist配置，根据配置加载指定的兼容性样式      
								plugins: [require("postcss-preset-env")()],
							},
						},
					},
				],
			},
			{
				test: /\.js$/,
				// 注意需要在package.json配置browserslist，否则babel-loader不生效
				// js兼容处理 babel
				loader: "babel-loader", // 规则只使用一个loader时推荐写法
				options: {
					presets: [
						[
							"@babel/preset-env",// 预设：指示babel做怎么样的兼容处理 
							{
								useBuiltIns: "usage", //按需加载
								corejs: {
									version: "3",
								},
								targets: "defaults",
							}
						]
					]
				}
			},
			/* 
			Webpack5.0新增资源模块(asset module)，它是一种模块类型，允许使用资源文件（字体，图标等）而无需     配置额外 loader。支持以下四个配置
			asset/resource 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现。
			asset/inline 导出一个资源的 data URI。之前通过使用 url-loader 实现。
			asset/source 导出资源的源代码。之前通过使用 raw-loader 实现。
			asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader，并且配置资     源体积限制实现。
			*/
			// Webpack4使用file-loader实现
			{
				test: /\.(eot|svg|ttf|woff|)$/,
				type: "asset/resource",
				generator: {
					// 输出文件位置以及文件名
					filename: "fonts/[name][ext]"
				},
			},
			// Webpack4使用url-loader实现
			{
				//处理图片资源
				test: /\.(jpg|png|gif|)$/,
				type: "asset",
				generator: {
					// 输出文件位置以及文件名
					filename: "images/[name][ext]"
				},
				parser: {
					dataUrlCondition: {
						maxSize: 10 * 1024 //超过10kb不转base64
					}
				}
			},
		],
	},
	module: {
		rules: [
			{
				test: /\.vue$/,
				loader: "vue-loader"
			},
			{
				test: /\.css$/,
				use: [
					// MiniCssExtractPlugin.loader的作用就是把css-loader处理好的样式资源（js文件内），单独提取出来 成为css样式文件
					MiniCssExtractPlugin.loader,//生产环境下使用，开发环境还是推荐使用style-loader
					"css-loader",
				],
			},
		],
	},
	plugins: [
		new HtmlWebpackPlugin({
			template: "index.html"
		}),
		new MiniCssExtractPlugin({
			filename: "css/built.css",
		}),
		new OptimizeCssAssetsWebpackPlugin(),
		new VueLoaderPlugin(),
	],
	// 解析模块的规则：
	resolve: {
		// 配置 解析模块路径别名：可简写路径。
		alias: {
			"@": path.resolve(__dirname, "src")
		},
		// 配置 省略文件路径的后缀名。默认省略js和json。也是webpack默认认识的两种文件类型
		extensions: [".js", ".json", ".css"], // 新加css文件
		// 告诉webpack解析模块是去找哪个目录
		// 该配置明确告诉webpack，直接去上一层找node_modules。
		modules: [path.resolve(__dirname, "../node_modules")],
	},
	// devServer（开发环境下配置）：
	devServer: {
		// 运行代码的目录
		contentBase: path.resolve(__dirname, "build"),
		// 为每个静态文件开启gzip压缩
		compress: true,
		host: "localhost",
		port: 5000,
		open: true, // 自动打开浏览器
		hot: true, //开启HMR功能
		// 设置代理
		proxy: {
			// 一旦devServer(5000端口)接收到/api/xxx的请求，就会用devServer起的服务把请求转发到另外一个服务器（3000）
			// 以此来解决开发中的跨域问题
			api: {
				target: "htttp://localhost:3000",
				// 发送请求时，请求路径重写：将/api/xxx  --> /xxx （去掉/api）
				pathRewrite: {
					"^api": "",
				},
			},
		},
	},
	// optimization（生产环境下配置）
	optimization: {
		// 提取公共代码
		splitChunks: {
			chunks: "all",
		},
		minimizer: [
			// 配置生产环境的压缩方案：js和css
			new TerserWebpackPlugin({
				// 多进程打包
				parallel: true,
				terserOptions: {
					// 启动source-map
					sourceMap: true,
				},
			}),
		],
	},
};

module.exports = config;